<?php

namespace app\model;

use support\Model;

/**
 * 商品SKU模型
 * 
 * 用于管理商品SKU相关数据
 * 包含规格组合、价格、库存等信息
 * 
 * @property int $id 主键ID
 * @property int|null $goods_id 商品ID
 * @property string|null $specs 规格组合字符串
 * @property int|null $v 库存值
 * @property string|null $created_at 创建时间
 * @property string|null $updated_at 更新时间
 * @property float|null $price 价格
 * @property string|null $specs_data 规格数据
 * @property string|null $name 名称
 */
class GoodsKuModel extends Model
{
    /**
     * 关联表名
     * @var string
     */
    protected $table = 'goods_ku';

    /**
     * 主键
     * @var string
     */
    protected $primaryKey = 'id';

    /**
     * 关闭自动时间戳
     * @var bool
     */
    public $timestamps = false;

    /**
     * 可批量赋值字段
     * @var array
     */
    protected $fillable = [
        'goods_id',
        'specs',
        'v',
        'price',
        'created_at',
        'updated_at',
        'pre_success_order_quantity_total'
    ];

    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
    ];

    protected $guarded = [];

    /**
     * 根据规格组合查找SKU（精确匹配）
     * @param int $goods_id 商品ID
     * @param string $specs 规格组合字符串
     * @return static|null
     */
    public static function findBySpecs(int $goods_id, string $specs)
    {
        return self::where('goods_id', $goods_id)
            ->where('specs', $specs)
            ->first();
    }

    /**
     * 根据规格组合查找SKU（支持顺序不一致）
     * 使用whereIn查询优化性能
     * @param int $goods_id 商品ID
     * @param string $specs 规格组合字符串
     * @return static|null
     */
    public static function findBySpecsFlexible(int $goods_id, string $specs)
    {
        // 先尝试精确匹配
        $sku = self::findBySpecs($goods_id, $specs);
        if ($sku) {
            return $sku;
        }

        // 如果精确匹配失败，使用whereIn查询所有可能的规格排列组合
        $specsArray = explode('@', $specs);
        
        // 生成所有可能的规格排列组合
        $specsPermutations = [];
        foreach (self::permute($specsArray) as $perm) {
            $specsPermutations[] = implode('@', $perm);
        }

        // 使用whereIn查询所有可能的规格组合
        return self::where('goods_id', $goods_id)
            ->whereIn('specs', $specsPermutations)
            ->first();
    }

    /**
     * 生成数组的所有排列组合
     * @param array $items 输入数组
     * @return array 所有排列组合
     */
    private static function permute($items)
    {
        if (count($items) <= 1) {
            return [$items];
        }
        
        $result = [];
        foreach ($items as $key => $item) {
            $rest = $items;
            unset($rest[$key]);
            foreach (self::permute(array_values($rest)) as $perm) {
                array_unshift($perm, $item);
                $result[] = $perm;
            }
        }
        
        return $result;
    }

    /**
     * 获取商品的所有SKU
     * @param int $goods_id 商品ID
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getByGoodsId(int $goods_id)
    {
        return self::where('goods_id', $goods_id)->get();
    }

    /**
     * 批量保存SKU数据
     * @param int $goods_id 商品ID
     * @param array $skuList SKU数据列表
     * @return array 返回操作结果
     */
    public static function batchSave(int $goods_id, array $skuList): array
    {
        $now = time();
        $result = [
            'success' => true,
            'message' => '保存成功',
            'details' => [
                'updated' => 0,
                'created' => 0,
                'deleted' => 0,
                'failed_to_delete' => []
            ]
        ];
        
        // 获取现有的SKU记录
        $existingSkus = self::where('goods_id', $goods_id)->get()->keyBy('specs');
        
        // 准备新的SKU规格组合
        $newSpecs = [];
        foreach ($skuList as $sku) {
            if (!empty($sku['specs']) && isset($sku['price']) && isset($sku['v'])) {
                $newSpecs[] = $sku['specs'];
            }
        }
        
        // 找出需要删除的SKU（在新数据中不存在的）
        $toDelete = [];
        foreach ($existingSkus as $specs => $sku) {
            if (!in_array($specs, $newSpecs)) {
                $toDelete[] = $sku->id;
            }
        }
        
        // 安全删除不再需要的SKU
        if (!empty($toDelete)) {
            $deleteResult = self::batchSafeDelete($toDelete);
            $result['details']['deleted'] = count($deleteResult['success']);
            $result['details']['failed_to_delete'] = $deleteResult['failed'];
            
            // 如果有SKU无法删除（被订单使用），给出警告
            if (!empty($deleteResult['failed'])) {
                $result['message'] = '部分SKU因被订单使用而无法删除，其他操作已完成';
            }
        }
        
        // 更新或插入SKU数据
        foreach ($skuList as $sku) {
            if (!empty($sku['specs']) && isset($sku['price']) && isset($sku['v'])) {
                $specs = $sku['specs'];
                $price = (float)$sku['price'];
                $stock = (int)$sku['v'];
                $pre_success_order_quantity_total = (int)$sku['pre_success_order_quantity_total'];
                if (isset($existingSkus[$specs])) {
                    // 更新现有SKU
                    $existingSkus[$specs]->update([
                        'price' => $price,
                        'v' => $stock,
                        'updated_at' => $now,
                        'pre_success_order_quantity_total' => $pre_success_order_quantity_total
                    ]);
                    $result['details']['updated']++;
                } else {
                    // 插入新SKU
                    self::create([
                        'goods_id' => $goods_id,
                        'specs' => $specs,
                        'price' => $price,
                        'v' => $stock,
                        'created_at' => $now,
                        'updated_at' => $now,
                        'pre_success_order_quantity_total' => $pre_success_order_quantity_total
                    ]);
                    $result['details']['created']++;
                }
            }
        }
        
        return $result;
    }

    /**
     * 生成SKU编码
     * @param int $goods_id 商品ID
     * @param string $specs 规格组合字符串
     * @return string
     */
    public static function generateSkuCode(int $goods_id, string $specs): string
    {
        return $goods_id . '_' . substr(md5($specs), 0, 8);
    }

    /**
     * 根据SKU编码查找SKU
     * @param string $sku_code SKU编码
     * @return static|null
     */
    public static function findBySkuCode(string $sku_code)
    {
        // 解析SKU编码：goods_id_hash
        $parts = explode('_', $sku_code);
        if (count($parts) !== 2) {
            return null;
        }
        
        $goods_id = (int)$parts[0];
        $hash = $parts[1];
        
        // 获取该商品的所有SKU，然后匹配哈希值
        $skus = self::where('goods_id', $goods_id)->get();
        foreach ($skus as $sku) {
            if (substr(md5($sku->specs), 0, 8) === $hash) {
                return $sku;
            }
        }
        
        return null;
    }

    /**
     * 检查SKU是否被订单使用
     * @param int $sku_id SKU ID
     * @return bool
     */
    public static function isUsedInOrders(int $sku_id): bool
    {
        // 检查order_items表中是否有引用该SKU的记录
        return \support\Db::table('order_items')
            ->where('goods_ku_id', $sku_id)
            ->exists();
    }

    /**
     * 安全删除SKU（检查是否被订单使用）
     * @param int $sku_id SKU ID
     * @return bool
     */
    public static function safeDelete(int $sku_id): bool
    {
        if (self::isUsedInOrders($sku_id)) {
            // 如果SKU被订单使用，则不允许删除
            return false;
        }
        
        return self::where('id', $sku_id)->delete() > 0;
    }

    /**
     * 批量安全删除SKU
     * @param array $sku_ids SKU ID数组
     * @return array 返回删除结果：['success' => [], 'failed' => []]
     */
    public static function batchSafeDelete(array $sku_ids): array
    {
        $result = [
            'success' => [],
            'failed' => []
        ];
        
        foreach ($sku_ids as $sku_id) {
            if (self::safeDelete($sku_id)) {
                $result['success'][] = $sku_id;
            } else {
                $result['failed'][] = $sku_id;
            }
        }
        
        return $result;
    }

    /**
     * 测试批量保存功能
     * @param int $goods_id 商品ID
     * @return array
     */
    public static function testBatchSave(int $goods_id): array
    {
        // 模拟测试数据
        $testSkuList = [
            [
                'specs' => '红色@XL',
                'price' => 99.99,
                'v' => 100
            ],
            [
                'specs' => '红色@L',
                'price' => 89.99,
                'v' => 50
            ],
            [
                'specs' => '蓝色@XL',
                'price' => 109.99,
                'v' => 30
            ]
        ];
        
        return self::batchSave($goods_id, $testSkuList);
    }
} 